package com.mall.controller;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.DTO.Useravatars;
import com.mall.Enum.Sex;
import com.mall.pojo.User;
import com.mall.service.IUserService;
import com.mall.utils.R;
import com.mall.vo.SearchUserVo;
import com.mall.vo.UserVo;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.mall.utils.R.success;

/**
 * 管理员管理用户
 *
 * @author cxx
 * @date 2023/4/24 21:47
 */
@RestController
@RequestMapping("/user")
@Validated
@SaCheckLogin
@Slf4j
public class UserController {
    @Resource
    private IUserService userService;

    /**
     * 管理员添加一个用户
     *
     * @param user 添加用户的各类信息 性别传递0或1
     * @return com.mall.utils.R<java.lang.String>
     * @author cxx
     * @date 2023/4/24 22:33
     */
    @SaCheckRole(value = {"admin", "super-admin"}, mode = SaMode.OR)
    @PostMapping("/add")
    @CacheEvict(value = "User", allEntries = true)
    public R<String> add(@Valid @RequestBody UserVo user) {
        User user1 = new User();
        BeanUtils.copyProperties(user, user1, "sex");
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(user1.getUsername()),
                User::getUsername, DigestUtils.md5Hex(user1.getUsername().getBytes()));
        List<User> list = userService.list(queryWrapper);
        if (!ObjectUtils.isEmpty(list)) {
            return R.error("添加失败，账号已经存在");
        }
        user1.setUsername(DigestUtils.md5Hex(user1.getUsername().getBytes()));
        user1.setPassword(DigestUtils.md5Hex(user1.getPassword().getBytes()));
        if (user.getSex() == 1) {
            user1.setSex(Sex.MAN);
        } else {
            user1.setSex(Sex.WOMAN);
        }
        boolean save = userService.save(user1);
        return save ? success("添加成功!") : R.error("添加失败!");
    }

    /**
     * 修改用户信息
     *
     * @param updateuser 用户的信息
     * @return com.mall.utils.R<java.lang.String>
     * @author cxx
     * @date 2023/4/24 22:39
     */
    @PutMapping("/update")
    @CacheEvict(value = "User", allEntries = true)
    @SaCheckPermission(value = "mine-update")
    public R<String> update(@Valid @RequestBody UserVo updateuser) {
        User user = new User();
        BeanUtils.copyProperties(updateuser, user);
        if (updateuser.getSex() == 1) {
            user.setSex(Sex.MAN);
        } else {
            user.setSex(Sex.WOMAN);
        }
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId, Long.valueOf(StpUtil.getLoginId().toString()))
                .set(StringUtils.isNotBlank(user.getPhone()), User::getPhone, user.getPhone())
                .set(StringUtils.isNotBlank(user.getPassword()), User::getPassword, DigestUtils.md5(user.getPhone().getBytes()))
                .set(StringUtils.isNotBlank(user.getEmail()), User::getEmail, user.getEmail())
                .set(StringUtils.isNotBlank(user.getTrueName()), User::getTrueName, user.getTrueName());
        boolean update = userService.update(wrapper);
        return update ? success("修改成功!") : R.error("修改失败!");
    }

    /**
     * 管理员批量删除用户
     *
     * @param userIds 要删除的用户id集合
     * @return com.mall.utils.R<java.lang.String>
     * @author cxx
     * @date 2023/4/24 22:52
     */
    @DeleteMapping("/delete/{userIds}")
    @SaCheckRole(value = {"admin", "super-admin"}, mode = SaMode.OR)
    @CacheEvict(value = "User", allEntries = true)
    public R<String> delete(@PathVariable List<Long> userIds) {
        boolean remove = userService.removeBatchByIds(userIds);
        return remove ? success("删除成功!") : R.error("删除失败!");
    }

    /**
     * 管理员分页查询用户,真实姓名可以不用传，不传则是搜索全部，页号和页码也可以不用传，不传则是默认的1和5
     *
     * @param page     页号
     * @param pageSize 页码大小
     * @param trueName 用户真实名
     * @return com.mall.utils.R<java.util.HashMap < java.lang.String, java.lang.Object>>
     * @author cxx
     * @date 2023/4/24 23:00
     */
    @GetMapping("/list")
    @SaCheckRole(value = {"admin", "super-admin"}, mode = SaMode.OR)
    @Cacheable(value = "User", unless = "#result.data.size()==0")
    public R<Object> list(@RequestParam(name = "page", required = false, defaultValue = "1") Integer page, @RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize, @RequestParam(name = "trueName", required = false) String trueName) {

        Page<User> usersPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(trueName), User::getTrueName, trueName);
        userService.page(usersPage, queryWrapper);
            log.error(usersPage.getRecords().toString());
        if (usersPage.getTotal() == 0) {
            return R.error("没有该用户", usersPage.getRecords());
        }

        List<SearchUserVo> collect = usersPage.getRecords().stream().map(item -> {
            SearchUserVo searchUserVo = new SearchUserVo();
            String[] ignoreProperties = {"status", "sex"};
            BeanUtils.copyProperties(item, searchUserVo, ignoreProperties);
            searchUserVo.setSex(item.getSex().getValue());
            if (item.getStatus() == 1) {
                searchUserVo.setStatus("正常");
            }
            if (item.getStatus() == 0) {
                searchUserVo.setStatus("禁用");
            }
            return searchUserVo;
        }).collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap<>(16);
        map.put("records", collect);
        map.put("total", usersPage.getTotal());

        return success(map);
    }

    /**
     * 批量禁用用户
     *
     * @param userIds 用户集合id
     * @return com.mall.utils.R<java.lang.String>
     * @author cxx
     * @date 2023/4/28 20:13
     */
    @PutMapping("/disable/{userIds}")
    @SaCheckRole(value = {"admin", "super-admin"}, mode = SaMode.OR)
    @CacheEvict(value = "User", allEntries = true)
    public R<String> disable(@PathVariable List<Long> userIds) {
        List<User> list = userIds.stream().map(k -> {
            User user = new User();
            user.setId(k);
            user.setStatus(0);
            return user;
        }).collect(Collectors.toList());
        boolean update = userService.updateBatchById(list);
        return update ? R.success("禁用用户成功!") : R.error("禁用用户失败!");
    }

    /**
     * 批量启用用户
     *
     * @param userIds 用户id集合
     * @return com.mall.utils.R<java.lang.String>
     * @author cxx
     * @date 2023/4/28 20:31
     */
    @PutMapping("/enable/{userIds}")
    @SaCheckRole(value = {"admin", "super-admin"}, mode = SaMode.OR)
    @CacheEvict(value = "User", allEntries = true)
    public R<String> enable(@PathVariable List<Long> userIds) {
        List<User> list = userIds.stream().map(k -> {
            User user = new User();
            user.setId(k);
            user.setStatus(1);
            return user;
        }).collect(Collectors.toList());
        boolean update = userService.updateBatchById(list);
        return update ? R.success("启用用户成功!") : R.error("启用用户失败!");
    }

    /**
     * 用户获取自己的信息
     *
     * @return
     * @author cxx
     * @date 2023/6/7 22:14
     */
    @SaCheckRole("user")
    @GetMapping("/getUserMsg")
    public R<Useravatars> getUserMsg() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, StpUtil.getLoginId().toString());
        User one = userService.getOne(wrapper);
        Useravatars useravatars = new Useravatars();
        BeanUtils.copyProperties(one, useravatars, "sex");
        useravatars.setSex(one.getSex().getValue());
        return R.success(useravatars);
    }
}
